using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using Peradigm.Framework.Domain.Collections;
using Peradigm.Framework.Domain.Collections.Generic;
using Peradigm.Framework.Domain.Security;
using Peradigm.Framework.Persistence;
using Peradigm.Framework.UI.Web;

using Liberty.Application.ApplicationManagement;
using Liberty.Application.ServiceMemberManagement;
using Liberty.Application.GrantManagement;
using Liberty.Application.Security;

using Liberty.Domain;
using Liberty.Domain.ApplicationManagement;
using Liberty.Domain.GrantManagement;
using Liberty.Domain.CaseManagement;
using Liberty.Domain.ServiceMemberManagement;

namespace Liberty.UI.GrantManagement.Controls
{
    public partial class GrantListView : AbstractLibertyControl
    {
        #region Constants
        private const string
            SORT_ASCENDING = "Ascending",
            SORT_DESCENDING = "Descending",
            SORT_ORDER = "SortOrder",
            DEFAULT_SORT_ORDER = "LastName",
            CMD_APPROVE_ID = "cmdApprove",
            CMD_DISPERSE_ID = "cmdDisperse",
            KEY_GRANT = "Grant",
            KEY_USER = "CurrentUser",

            COMMAND_NAME_SERVICE_MAN_SELECTED = "ServiceManSelected",
            COMMAND_NAME_APPROVE = "Approve",
            COMMAND_NAME_DISPERSE = "Disperse",
            COMMAND_GRANT_AMOUNT_SELECTED = "GrantAmountSelected";

        #endregion

        #region Event Handlers
        protected void Page_Load( object sender, EventArgs e )
        {
            this.BuildGridViewCommandHandlers();
#warning Handle this better
#if OLD_CODE
            if( this.SortedListFrom( (List<Grant>)this.Model ).Count > 0 )
            {
                this.divNumRows.Visible = true;
            }
            else
            {
                this.divNumRows.Visible = false;
            }
#endif

            if( !this.IsPostBack )
            {
                if( Profile.NumRows == 0 )
                    Profile.NumRows = 10;
                this.ddlNumRows.Items.FindByValue( Profile.NumRows.ToString() ).Selected = true;
                this.gvGrantList.PageSize = Profile.NumRows;
            }
        }

        protected void gvGrantList_RowCommand( object sender, GridViewCommandEventArgs e )
        {
            if( this.GridViewCommandHandlers.ContainsKey( e.CommandName ) )
            {
                GridViewCommandHandler handler = this.GridViewCommandHandlers[e.CommandName];
                handler( e );
            }
        }

        protected void ddlNumRows_SelectedIndexChanged( object sender, EventArgs e )
        {
            Profile.NumRows = Convert.ToInt32( ddlNumRows.SelectedValue );
            this.gvGrantList.PageSize = Profile.NumRows;
        }

        protected void gvGrantList_RowDataBound( object sender, GridViewRowEventArgs e )
        {
            if( e.Row.RowType == DataControlRowType.DataRow )
            {
                Grant grant = (Grant)e.Row.DataItem;
                bool canApprove = this.CanUserApprove( grant );
                bool canDisperse = this.CanUserDisperse( grant );

                Button cmdApprove = (Button)e.Row.FindControl( CMD_APPROVE_ID );
                Button cmdDisperse = (Button)e.Row.FindControl( CMD_DISPERSE_ID );
                cmdApprove.Visible = false;
                cmdDisperse.Visible = false;
                if( canApprove )
                {
                    cmdApprove.Visible = true;
                    cmdDisperse.Visible = false;
                }
                else if( canDisperse )
                {
                    cmdDisperse.Visible = true;
                    cmdApprove.Visible = false;
                }
            }
        }

        protected void gvGrantList_Sorting( object sender, GridViewSortEventArgs e )
        {
            this.SetSortOrderUsing( e.SortExpression );

            ObjectDataSource1.SelectParameters["sortBy"].DefaultValue = this.SortExpression;
            ObjectDataSource1.SelectParameters["sortDirection"].DefaultValue = this.SortDirection.ToString();

            e.Cancel = true;
        }

        protected void ObjectDataSource1_Selecting( object sender, ObjectDataSourceSelectingEventArgs e )
        {
            e.InputParameters.Clear();

            UserVariable user = new UserVariable();
            e.InputParameters["aVolunteer"] = user.User;
            if( !e.ExecutingSelectCount )
            {
                e.InputParameters["sortBy"] = this.SortExpression;
                e.InputParameters["sortDirection"] = this.SortDirection.ToString();
            }
        }

        #endregion

        #region Methods

        protected string DisplayFacility( Case aCase )
        {
            string facility = String.Empty;
            if( aCase.CurrentVisit.Facility != null )
            {
                facility = aCase.CurrentVisit.Facility.Name;
            }
            return facility;
        }

        public override void UpdateView()
        {
        }

        public void InitializeView()
        {
        }
        #endregion

        #region Properties
        /// <summary>
        /// Delegate to register callbacks of the type ServiceMemberSelected.
        /// </summary>
        public event ServiceMemberSelectedEventHandler ServiceMemberSelectedListeners
        {
            add
            {
                i_ServiceMemberSelectedEvent += value;
            }
            remove
            {
                i_ServiceMemberSelectedEvent -= value;
            }
        }

        /// <summary>
        /// Delegate to register callbacks of the type GrantSelected.
        /// </summary>
        public event GrantSelectedEventHandler GrantSelectedListeners
        {
            add
            {
                i_GrantSelectedEvent += value;
            }
            remove
            {
                i_GrantSelectedEvent -= value;
            }
        }

        /// <summary>
        /// Delegate to register callbacks of the type RecipientSelected.
        /// </summary>
        public event RecipientSelectedEventHandler RecipientSelectedListeners
        {
            add
            {
                i_RecipientSelectedEvent += value;
            }
            remove
            {
                i_RecipientSelectedEvent -= value;
            }
        }
        #endregion

        #region Private Methods
        private void BuildGridViewCommandHandlers()
        {
            this.GridViewCommandHandlers = new Dictionary<string, GridViewCommandHandler>();
            this.GridViewCommandHandlers.Add( COMMAND_NAME_SERVICE_MAN_SELECTED, new GridViewCommandHandler( this.ServiceMemberSelectedHandler ) );
            this.GridViewCommandHandlers.Add( COMMAND_GRANT_AMOUNT_SELECTED, new GridViewCommandHandler( this.GrantAmountSelectedHandler ) );
            this.GridViewCommandHandlers.Add( COMMAND_NAME_APPROVE, new GridViewCommandHandler( this.GrantApprovedHandler ) );
            this.GridViewCommandHandlers.Add( COMMAND_NAME_DISPERSE, new GridViewCommandHandler( this.GrantDispersedHandler ) );
        }

        private void ServiceMemberSelectedHandler( GridViewCommandEventArgs e )
        {
            ServiceMember servicemember = this.ServiceMemberWith( Convert.ToInt64( e.CommandArgument ) );
            this.RaiseServiceMemberSelectedEvent( servicemember );
        }

        private void GrantAmountSelectedHandler( GridViewCommandEventArgs e )
        {
            Grant SelectGrant = this.GrantWith( Convert.ToInt64( e.CommandArgument ) );
            this.RaiseGrantAmountSelectedEvent( SelectGrant );
        }

        private void GrantApprovedHandler( GridViewCommandEventArgs e )
        {
            Grant grant = this.GrantWith( Convert.ToInt64( e.CommandArgument ) );
            this.ApproveGrant( grant );
        }

        private void GrantDispersedHandler( GridViewCommandEventArgs e )
        {
            Grant grant = this.GrantWith( Convert.ToInt64( e.CommandArgument ) );
            this.DisperseGrant( grant );
        }

        private void ApproveGrant( Grant grant )
        {
            grant.ApproveBy( this.User );
            new GrantController().SaveGrant( grant );
        }

        private void DisperseGrant( Grant grant )
        {
            grant.DisperseBy( this.User );
            new GrantController().SaveGrant( grant );
        }

        private bool CanUserApprove( Grant grant )
        {
            Dictionary<string, object> context = new Dictionary<string, object>();
            context.Add( ViewGrantPrivilege.KEY_USER, this.User );
            context.Add( ViewGrantPrivilege.KEY_GRANT, grant );
            return this.User.HasPermissionTo( Privilege.Actions.Approve, context );
        }

        private bool CanUserDisperse( Grant grant )
        {
            Dictionary<string, object> context = new Dictionary<string, object>();
            context.Add( ViewGrantPrivilege.KEY_USER, this.User );
            context.Add( ViewGrantPrivilege.KEY_GRANT, grant );
            context.Add( DisperseGrantPrivilege.PRIVILEGE_DISPERSE_GRANT, DisperseGrantPrivilege.PRIVILEGE_DISPERSE_GRANT );
            return this.User.HasPermissionTo( Privilege.Actions.Approve, context );
        }

        private ServiceMember ServiceMemberWith( long id )
        {
            ServiceMemberController controller = new ServiceMemberController();
            return controller.ServiceMemberWith( id );
        }

        private Grant GrantWith( long oid )
        {
            GrantController controller = new GrantController();
            return controller.GrantWith( oid );
        }

        private Applicant RecipientWith( long id )
        {
            ApplicantController controller = new ApplicantController();
            return controller.ApplicantWith( id );
        }

        private void RaiseServiceMemberSelectedEvent( ServiceMember serviceMember )
        {
            if( this.ServiceMemberSelectedEvent != null )
            {
                this.ServiceMemberSelectedEvent( serviceMember );
            }
        }

        private void RaiseGrantAmountSelectedEvent( Grant selectedGrant )
        {
            if( this.GrantSelectedEvent != null )
            {
                this.GrantSelectedEvent( selectedGrant );
            }
        }

        private void RaiseRecipientMemberSelectedEvent( Applicant recipient )
        {
            if( this.RecipientSelectedEvent != null )
            {
                this.RecipientSelectedEvent( recipient );
            }
        }

        private void SetSortOrderUsing( string newSortExpression )
        {
            if( newSortExpression != String.Empty )
            {
                if( newSortExpression == this.SortExpression )
                {
                    this.SortDirection = this.SortDirection == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;
                }
                else
                {
                    this.SortDirection = SortOrder.Ascending;
                }
                this.SortExpression = newSortExpression;
            }
        }

        private SortOrder SortDirection
        {
            get
            {
                if( this.ViewState[SORT_ORDER] == null )
                {
                    this.ViewState[SORT_ORDER] = SORT_ASCENDING;
                }
                string sortDirection = this.ViewState[SORT_ORDER].ToString();
                return sortDirection == SORT_ASCENDING ? SortOrder.Ascending : SortOrder.Descending;

            }
            set
            {
                this.ViewState[SORT_ORDER] = value == SortOrder.Ascending ? SORT_ASCENDING : SORT_DESCENDING;
            }
        }

        private string SortExpression
        {
            get
            {
                if( this.ViewState["SortExpression"] == null )
                {
                    this.ViewState["SortExpression"] = DEFAULT_SORT_ORDER;
                }
                return this.ViewState["SortExpression"].ToString();
            }
            set
            {
                this.ViewState["SortExpression"] = value;
            }
        }
        #endregion

        #region Private Properties
        private ServiceMemberSelectedEventHandler ServiceMemberSelectedEvent
        {
            get
            {
                return i_ServiceMemberSelectedEvent;
            }
        }

        private GrantSelectedEventHandler GrantSelectedEvent
        {
            get
            {
                return i_GrantSelectedEvent;
            }
        }

        private RecipientSelectedEventHandler RecipientSelectedEvent
        {
            get
            {
                return i_RecipientSelectedEvent;
            }
        }
        private Dictionary<string, GridViewCommandHandler> GridViewCommandHandlers
        {
            get
            {
                return i_GridViewCommandHandlers;
            }
            set
            {
                i_GridViewCommandHandlers = value;
            }
        }
        #endregion

        #region Data Elements
        private ServiceMemberSelectedEventHandler i_ServiceMemberSelectedEvent;
        private GrantSelectedEventHandler i_GrantSelectedEvent;
        private RecipientSelectedEventHandler i_RecipientSelectedEvent;
        private delegate void GridViewCommandHandler( GridViewCommandEventArgs e );
        private Dictionary<string, GridViewCommandHandler> i_GridViewCommandHandlers;
        #endregion

    }
}
